package cn.mulanbay.business.handler;

import cn.mulanbay.common.config.Constants;
import cn.mulanbay.common.exception.ErrorCode;
import cn.mulanbay.common.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import javax.servlet.http.HttpServletRequest;

/**
 * Feign内部验证
 */
public class FeignCheckHandler extends BaseHandler{

    private static final Logger logger = LoggerFactory.getLogger(FeignCheckHandler.class);

    /**
     * feign内部的密码
     */
    @Value("${security.feign.password:111222}")
    String feignPwd;

    /**
     * 是否需要进行feign认证
     */
    @Value("${security.feign.check:true}")
    boolean feignCheck;

    /**
     * 是否需要进行时间戳认证
     */
    @Value("${security.feign.timestampCheck:true}")
    boolean timestampCheck;

    /**
     * 认证码的失效时间（秒）
     */
    @Value("${security.feign.expires:300}")
    long feignExpires;

    @Autowired
    PasswordHandler passwordHandler;

    public FeignCheckHandler() {
        super("Feign验证");
    }

    /**
     * feign内部调用的安全认证
     * @param request
     */
    public int checkFeignAuth(HttpServletRequest request){
        try {
            //第一步先判断是否有信心
            String feignHeader = request.getHeader(Constants.FEIGN_AUTH_HEADER);
            logger.debug("feignHeader:"+feignHeader);
            if(StringUtil.isEmpty(feignHeader)){
                return ErrorCode.FEIGN_HEADER_NULL;
            }
            //如果不验证具体内容值，说明只需要判断是否有header信息
            if(feignCheck==false){
                return ErrorCode.SUCCESS;
            }
            String authInfo = passwordHandler.decodePassword(feignHeader);
            if(StringUtil.isEmpty(authInfo)){
                return ErrorCode.FEIGN_PWD_NULL;
            }
            String[] ais = authInfo.split(",");
            /**
             * 时间戳，如果两台服务器的时钟相差很大会导致服务不可用
             */
            long sd = Long.valueOf(Long.valueOf(ais[1]));
            if((timestampCheck&&(System.currentTimeMillis()-sd) >feignExpires*1000)){
                return ErrorCode.FEIGN_PWD_EXPIRED;
            }
            if(!feignPwd.equals(ais[0])){
                return ErrorCode.FEIGN_PWD_ERROR;
            }
            return ErrorCode.SUCCESS;
        } catch (Exception e) {
            logger.error("feign内部调用的安全认证异常",e);
            return ErrorCode.FEIGN_PWD_CHECK_ERROR;
        }
    }
}
